package common;

/**
 * Rectangle A cartesian integer rectangle.
 **/

public class Rectangle {
	public static int DEFAULT_WIDTH = 16;
	public static int DEFAULT_HEIGHT = 16;
	public Rectangle(int x, int y, int width, int height) {
		X = x;
		Y = y;
		Width = width;
		Height = height;
	}
	public Rectangle(int width, int height) {
		X = 0;
		Y = 0;
		Width = width;
		Height = height;
	}
	public Rectangle() {
		X = 0;
		Y = 0;
		Width = DEFAULT_WIDTH;
		Height = DEFAULT_HEIGHT;
	}
	
	/**
	 * Copies this rectangle into an existing rectangle class.
	 * @param outRect - The rectangle to copy data to.
	 * @returns If outRect was null, a new copy of this rectangle. Otherwise it returns the instance provided to this
	 * method.
	 **/
	public Rectangle copyTo(Rectangle outRect) {
		if(outRect == null) {
			return new Rectangle(X, Y, Width, Height);
		}
		outRect.X = X;
		outRect.Y = Y;
		outRect.Width = Width;
		outRect.Height = Height;
		return outRect;
	}

	/**
	 * Compares this rectangle with another rectangle for intersection.
	 * 
	 * @param other
	 *            - the rectangle to test against
	 * @returns True if this rectangle overlaps the other rectangle, otherwise
	 *          false.
	 **/
	public boolean overlaps(Rectangle other) {
		int ax1, ax2, ay1, ay2;
		ax1 = X;
		ax2 = ax1 + Width;
		ay1 = Y;
		ay2 = ay1 + Height;

		int bx1, bx2, by1, by2;
		bx1 = other.X;
		bx2 = bx1 + other.Width;
		by1 = other.Y;
		by2 = by1 + other.Height;
		
		// Separating axis theorem.
		return ((ax1 > bx1) | (ax2 > bx1) && (ax1 < bx2) | (ax2 < bx2))
										  &&
			   ((ay1 > by1) | (ay2 > by1) && (ay1 < by2) | (ay2 < by2));
	}
	public boolean contains(Rectangle other) {
		int ax1, ax2, ay1, ay2;
		ax1 = X;
		ax2 = ax1 + Width;
		ay1 = Y;
		ay2 = ay1 + Height;

		int bx1, bx2, by1, by2;
		bx1 = other.X;
		bx2 = bx1 + other.Width;
		by1 = other.Y;
		by2 = by1 + other.Height;
		
		return ((ax1 <= bx1 && ax1 <= bx2) && (ax2 >= bx1 && ax2 >= bx2)) 
				&& ((ay1 <= by1 && ay1 <= by2) && (ay2 >= by1 && ay2 >= by2)); 
	}

	public int X;
	public int Y;
	public int Width;
	public int Height;
	/**
	 * Clips two rectangles and returns the overlapping area. Returns null if
	 * they do not overlap.
	 * 
	 * @param A
	 *            Rectangle A
	 * @param B
	 *            Rectangle B
	 * @return A new rectangle which is the overlapping area of the two
	 *         arguments.
	 */
	public static Rectangle Clip(Rectangle A, Rectangle B) {
		if (A == null || B == null) {
			return null;
		}

		int left, right, top, bot;

		left = Math.max(A.X, B.X);
		right = Math.min(A.X + A.Width, B.X + B.Width);

		// trivial rejection
		if (right <= left) {
			return null;
		}
		top = Math.max(A.Y, B.Y);
		bot = Math.min(A.Y + A.Height, B.Y + B.Height);
		// trivial rejection
		if (bot <= top) {
			return null;
		}
		return new Rectangle(left, top, right - left, bot - top);
	}
	@Override
	public String toString() {
		return new String("[X:" + X + " Y:" + Y + "] [W:" + Width + " H:" + Height + "]");
	}
	@Override
	public Rectangle clone() {
		return new Rectangle(X, Y, Width, Height);
	}
}
